Conversión y adaptación de documentos XML

Ya vimos que HTML es un lenguaje de marcas presentacional que, si bien es adecuado para la visualización directa en navegadores, carece de la capacidad semántica necesaria para describir los datos que contiene, mezclando contenido con su apariencia visual. Además, presenta limitaciones cuando necesitamos intercambiar, procesar o reutilizar esos datos en diferentes sistemas o formatos sin "arrastrar" su estructura de diseño

En el ecosistema de XML existen tecnologías diseñadas específicamente para transformar los datos de los documentos en formatos que sean visualmente atractivos sin perder las ventajas que proporciona XML. Aquí entra en juego XSL (eXtensible Stylesheet Language - Lenguaje de hojas de eStilo eXtensible)

Familia de lenguajes XSL

XSL no es un único lenguaje, sino un conjunto de "herramientas" desarrolladas por el W3C que tienen como objetivo la transformación de documentos XML. XML sería qué queremos representar (los datos), mientras que XSL sería cómo lo queremos representar. Se divide principalmente en 3 componentes:

El estado actual de XSL

En el desarrollo web moderno, tanto XSLT como XSL-FO han sido parcialmente sustituidos por el uso combinado de CSS y librerías de JavaScript.

Sin embargo, a JavaScript "le gusta más" el formato JSON (JavaScript Object Notation), ya que es más ligero para el navegador. Por otro lado, XSLT sigue siendo una herramienta importante en entornos de servidor y procesos de intercambio de datos. Por tanto, en esta unidad veremos algunos aspectos esenciales de XSLT para comprender cómo transformar datos estructurados antes de dar el salto al ecosistema de JavaScript y JSON.

XSLT

El procesador de XSLT necesita de 3 elementos fundamentales:

El procesador lee el XML como un árbol de nodos, utilizando XPath para encontrar partes específicas, y aplica reglas definidas en el XSLT para construir un nuevo árbol de salida. Este árbol de salida puede ser XML, HTML o incluso texto plano. La mayor ventaja de este sistema es la separación entre contenido y presentación. Para el mismo conjunto de datos podemos tener varias representaciones sin que esto afecte a los datos

Notas de seguridad

Por cuestiones de seguridad, muchos navegadores bloquean el motor de XSLT cuando cargan el XML desde un sistema de ficheros. Para poder utilizar el navegador como procesador de XSLT, tenemos 2 alternativas:

Estructura

El documento XML debe incluir una referencia al documento XSL:

<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="biblioteca.xsl"?>
...

El documento XLS está basado en XML y debe incluir obligatoriamente la declaración del espacio de nombres de XSL

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
    …
    </xsl:template>
</xsl:stylesheet>

La línea <xsl:template match="/"> es el punto de entrada al procesamiento del XML e indica que se va a aplicar una transformación sobre todo el documento. Si quisiéramos aplicar la transformación sobre una parte específica, se indicaría como valor del atributo match, pero lo habitual es utilizar /

Ejemplo sencillo

Documento biblioteca.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="biblioteca.xsl"?>
<biblioteca>
  <libro genero="ciencia-ficcion">
    <titulo>Dune</titulo>
    <autor>Frank Herbert</autor>
  </libro>
</biblioteca>

Documento biblioteca.xsl:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
    	<html>
        	<head>
            	<title>Mi biblioteca</title>
            </head>
            <body>
                <h1>Mi biblioteca</h1>
                <h2><xsl:value-of select="biblioteca/libro/titulo" /></h2>
                <p><strong>Autor: </strong> <xsl:value-of select="biblioteca/libro/autor" /></p>
                <p><strong>Género: </strong> <xsl:value-of select="biblioteca/libro/@genero" /></p>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

Transformación

Como habrás apreciado en el ejemplo anterior, en un documento XSL se alterna texto libre (normalmente HTML) con elementos propios de XSL.

A esto se lo conoce como integración con lenguaje de marcas. Esta forma de trabajar es muy típica de los lenguajes de servidor web, como PHP. Al igual que en XSLT el HTML se mezcla con <xsl:...>, en PHP se mezcla con <?php ...?>. La lógica es la misma: el servidor procesa los el código dinámico, inyecta los datos y le entrega al navegador un código HTML limpio. Aprender XSLT proporciona una base para entender cómo se genera una web dinámica.

En el ejemplo, mostramos el valor del elemento <titulo> en una cabecera de nivel 2 <h2>, el valor del elemento <autor> en un párrafo <p> y el valor del atributo "genero" en otro párrafo <p>. Al abrir el documento XML con un transformador, podremos visualizar lo siguiente:

Elementos de XSLT

XSLT tiene un número extenso de elementos para transformar el documento XML, pero estos son los más importantes

xsl:value-of

Obtiene el valor de un elemento o de un atributo del documento XML

<!-- Sintaxis -->
<xsl:value-of select="expresión XPath"/>

<!-- Ejemplo -->
<h2><xsl:value-of select="biblioteca/libro/titulo" /></h2>

xsl:for-each

Recorre un conjunto de nodos

<!-- Sintaxis -->
<xsl:for-each select="expresión XPath">
</xsl:for-each>

<!-- Ejemplo -->
<xsl:for-each select="//zulo">
	...
</xsl:for-each>

xsl:sort

Ordena un conjunto de nodos. Muy frecuentemente se utiliza dentro de un xsl:for-each, siempre en la primera línea

<!-- Sintaxis -->
<xsl:sort select="nombre del elemento por el que se quiere ordenar"/>

<!-- Ejemplo -->
<xsl:for-each select="//zulo">
    <xsl:sort select="precio"/>
	...
</xsl:for-each>

xsl:if

Permite condicionar la transformación en función de una condición. Problema: no tiene else if ni else

<!-- Sintaxis -->
<xsl:if test="expresión">
    ...
</xsl:if>

<!-- Ejemplo -->
<xsl:if test="precio > 500">
    <p>Muy caro</p>
</xsl:if>

xsl:choose

Es la versión "completa" de xsl:if. Cuando queramos evaluar varias condiciones y ofrecer una transformación alternativa si no se cumple ninguna, deberemos utilizarlo junto con xsl:when y xsl:otherwise

<!-- Sintaxis -->
<xsl:choose>
	<xsl:when test="expresión">
    	...
    </xsl:when>
    <xsl:otherwise>
    	...
    </xsl:otherwise>
</xsl:choose>

<!-- Ejemplo -->
<xsl:choose>
	<xsl:when test="precio > 500">
    	<p>Muy caro</p>
    </xsl:when>
    <xsl:otherwise>
    	<p>Precio inmejorable</p>
    </xsl:otherwise>
</xsl:choose>

xsl:variable

Permite almacenar un valor para reutilizarlo en varios puntos del documento. Es importante recordar que en XSLT las variables son "inmutables": una vez que le asignas un valor, no puedes cambiarlo (funcionan más bien como constantes). La manera de referenciar a las variables es igual que en XQuery, con $variable

<!-- Sintaxis -->
<xsl:variable name="nombre_variable" select="expresión XPath"/>


<xsl:for-each select="//zulo">
	<xsl:variable name="zulo" select="."/>
</xsl:for-each>

xsl:attribute

Se utiliza para crear atributos de forma dinámica dentro de una etiqueta HTML o XML. Es muy útil cuando el valor de un atributo (como un href de un enlace o un src de una imagen) proviene del XML

<!-- Sintaxis -->
<xsl:attribute name="nombre_del_atributo">valor</xsl:attribute>

<!-- Ejemplo -->
<a>
  <xsl:attribute name="href">
    <xsl:value-of select="sitio_web/url"/>
  </xsl:attribute>
  Ver más información
</a>

xsl:text

Se utiliza para escribir texto literal en la salida, especialmente útil para forzar espacios en blanco, saltos de línea o caracteres especiales que el procesador XSLT podría ignorar o comprimir

<!-- Sintaxis -->
<xsl:text>Texto literal</xsl:text>

<!-- Ejemplo -->
<xsl:value-of select="nombre"/>
<xsl:text> </xsl:text> <xsl:value-of select="apellido"/>